﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

namespace Ratatoskr.Toolbox
{
    class HexCell : Cell
    {
        protected static float _minimumDiameter = (float)Math.Sqrt(3);
        protected static float _yOffset = _minimumDiameter / 2;
        protected static Vector2 _aspect = new Vector2(2, _minimumDiameter);
        public new static Vector2 Aspect
        {
            get { return _aspect; }
        }
        public new static float Constraint
        {
            get { return _minimumDiameter; }
        }

        public HexCell(ParentEntity parent, int xLoc, int yLoc)
            : base(xLoc, yLoc, 6) { }

        protected internal override void FindAdjacentCells()
        {
            Grid<HexCell> grid = _parent as Grid<HexCell>;
            if (grid == null)
                throw new ArgumentNullException("Cannot find adjacent cells without a grid parent.");
            _adjacent = new Cell[6];
            bool leftmost = (_xLoc == grid.MinExtent.X);
            bool rightmost = (_xLoc == grid.MaxExtent.X);
            bool top = (_yLoc == grid.MinExtent.Y);
            bool bottom = (_yLoc == grid.MaxExtent.Y);
            bool offset = (_yLoc % 2 == 1);
            if (!top)
                _adjacent[0] = grid[_xLoc, _yLoc - 1];
            if (!rightmost && (!top || offset))
                _adjacent[1] = grid[_xLoc + 1, offset ? _yLoc : _yLoc - 1];
            if (!rightmost && (!bottom || !offset))
                _adjacent[2] = grid[_xLoc + 1, offset ? _yLoc + 1 : _yLoc];
            if (!bottom)
                _adjacent[3] = grid[_xLoc, _yLoc + 1];
            if (!leftmost && (!bottom || !offset))
                _adjacent[4] = grid[_xLoc - 1, offset ? _yLoc + 1 : _yLoc];
            if (!leftmost && (!top || offset))
                _adjacent[5] = grid[_xLoc - 1, offset ? _yLoc : _yLoc - 1];
        }

        protected internal override CellPosition _CellStep(float x, float y)
        {
            Cell c = this;
            float x2 = x;
            float y2 = y;
            if (Math.Abs(x) > 0.5)
            {
                if (Math.Abs(x) > 1 || Math.Abs(y) > (_minimumDiameter * (1 - Math.Abs(x))))
                {
                    if (x > 0)
                    {
                        x2 -= 1.5f;
                        if (y > 0)
                        {
                            y2 -= _yOffset;
                            c = _adjacent[1];
                        }
                        else
                        {
                            y2 += _yOffset;
                            c = _adjacent[2];
                        }
                    }
                    else
                    {
                        x2 += 1.5f;
                        if (y > 0)
                        {
                            y2 -= _yOffset;
                            c = _adjacent[5];
                        }
                        else
                        {
                            y2 += _yOffset;
                            c = _adjacent[4];
                        }
                    }
                }
            }
            else if (y > _yOffset)
            {
                y2 -= _yOffset;
                c = _adjacent[0];
            }
            else if (y < -_yOffset)
            {
                y2 += _yOffset;
                c = _adjacent[3];
            }
            if (c == null)
                return new CellPosition(this, x, y, true);
            return new CellPosition(c, x, y);
        }
    }
}

